home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 23 / CU Amiga - Super CD-ROM 23 (June 1998).iso / CUCD / Graphics / STIMP_noise / source / pgmmedian / pgmmedian.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-30  |  4.2 KB  |  214 lines

  1.  
  2. /************************************************************************/
  3. #define OP_NAME      "pgmmedian"
  4. #define VERSION      "1.03"
  5. #define DATE         "30.01.98"
  6. #define AUTHOR       "Stefan Diener"
  7. /************************************************************************/
  8.  
  9. #include <stdio.h>
  10. #include <stdarg.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <sys/types.h>
  14.  
  15. #include <STIMP/pgm.c>
  16.  
  17. struct PGM_Info source, desti;
  18. static int m, n;
  19. static int edge=1, edgex, edgey;
  20. static int form=1;
  21.  
  22. unsigned char median(unsigned char *feld, int anzahl)
  23. /* Bucket-Sort und mittleres Element zurueckgeben */
  24. {
  25.   int i, mitte=anzahl/2, summe=0;
  26.   static unsigned char bucket[256];
  27.  
  28.   /* Buckets leeren */
  29.   for (i=0; i<256;) bucket[i++]=0;
  30.  
  31.   /* Buckets fuellen */
  32.   for (i=0; i<anzahl;) bucket[feld[i++]]++;
  33.  
  34.   /* Mitte suchen */
  35.   for (i=0; i<256; i++)
  36.   {
  37.     if (bucket[i])
  38.     {
  39.       summe+=bucket[i];
  40.       if (summe>mitte) return (unsigned char) i;
  41.     }
  42.   }
  43.  
  44.   /* durchgelaufen ??? */
  45.   return 255;
  46. }
  47.  
  48. void Do_It_normal(void)
  49. {
  50.   int i, x, y, k, l, index;
  51.   unsigned char array[81];
  52.   unsigned char *src, *dst;
  53.  
  54.   /* Zeiger auf Bilddaten holen */
  55.   src=source.Data;
  56.   dst=desti.Data;
  57.   desti.maxval=source.maxval;
  58.  
  59.   /* fuer jeden Punkt ausser Rand */
  60.   for (y=edgey; y<m-edgey; y++)
  61.     for (x=edgex; x<n-edgex; x++)
  62.     {
  63.       /* Position berechnen */
  64.       index=y*n+x;
  65.       i=0;
  66.  
  67.       /* Feld fuellen */
  68.       for (l=-edgey; l<=edgey; l++)
  69.         for (k=-edgex; k<=edgex; k++)
  70.           array[i++]=src[index+l*n+k];
  71.  
  72.       /* Median des Feldes bestimmen */
  73.       dst[(y-edgey)*(n-2*edgex)+x-edgex]=median(array, i);
  74.     }
  75. }
  76.  
  77. void Do_It_plus(void)
  78. {
  79.   int i, x, y, k, l, index;
  80.   unsigned char array[18];
  81.   unsigned char *src, *dst;
  82.  
  83.   /* Zeiger auf Bilddaten holen */
  84.   src=source.Data;
  85.   dst=desti.Data;
  86.   desti.maxval=source.maxval;
  87.  
  88.   /* fuer jeden Punkt ausser Rand */
  89.   for (y=edgey; y<m-edgey; y++)
  90.     for (x=edgex; x<n-edgex; x++)
  91.     {
  92.       /* Position berechnen */
  93.       index=y*n+x;
  94.       i=0;
  95.  
  96.       /* Feld fuellen */
  97.       for (l=-edgey; l<=edgey; l++) array[i++]=src[index+l*n];
  98.  
  99.       for (k=-edgex; k<=edgex; k++)
  100.         if (k!=0) array[i++]=src[index+k];
  101.  
  102.       /* Median des Feldes bestimmen */
  103.       dst[(y-edgey)*(n-2*edgex)+x-edgex]=median(array, i);
  104.     }
  105. }
  106.  
  107. int main(int argc,char **argv)
  108. /* main program */
  109. {
  110.   int i;
  111.  
  112.   /* say hello */
  113.   PrintOpening(argc,argv);
  114.  
  115.   /* read the parameters */
  116.   for (i=1; i<argc; i++)
  117.   {
  118.     if ((argv[i][0]=='-') && argv[i][1])
  119.     {
  120.       switch (argv[i][1])
  121.       {
  122.         case '3': edge=1;
  123.                       break;
  124.  
  125.         case '5': edge=2;
  126.                       break;
  127.  
  128.         case '7': edge=3;
  129.                       break;
  130.  
  131.         case '9': edge=4;
  132.                       break;
  133.  
  134.         case 'e': form=3;
  135.                       break;
  136.  
  137.         case 'h': form=2;
  138.                       break;
  139.  
  140.         case 'q': form=0;
  141.                       break;
  142.  
  143.         case 'p': form=1;
  144.                       break;
  145.  
  146.         case 'v': beVerbose=FALSE;
  147.                       break;
  148.  
  149.         default: PrintMessage("Unknown parameter: %s", argv[i]);
  150.                      Hilfe();
  151.                      exit(-1);
  152.                      break;
  153.       }
  154.     }
  155.  
  156.     if (argv[i][0]=='+')
  157.     {
  158.       switch (argv[i][1])
  159.       {
  160.         case 'v': beVerbose=TRUE;
  161.                       break;
  162.  
  163.         default: PrintMessage("Unknown parameter: %s", argv[i]);
  164.                      Hilfe();
  165.                      exit(-1);
  166.                      break;
  167.       }
  168.     }
  169.   }
  170.  
  171.   /* check minimal number of arguments */
  172.   if (argc<3)
  173.   {
  174.     PrintMessage("Not enough arguments !");
  175.     Hilfe();
  176.     exit(-1);
  177.   }
  178.  
  179.   /* check number of file names */
  180.   if (FilenameCount(argc, argv)!=2)
  181.   {
  182.     PrintMessage("Wrong number of file names !");
  183.     Hilfe();
  184.     exit(-1);
  185.   }
  186.  
  187.   if (ReadPGMFile(GetFilename(1,argc,argv),&source)==0)
  188.   {
  189.     m=source.height;
  190.     n=source.width;
  191.  
  192.     /* Aussenraender festlegen */
  193.     edgex=(form==3) ? 0 : edge;
  194.     edgey=(form==2) ? 0 : edge;
  195.  
  196.     if (CreatePGMArray(m-2*edgey, n-2*edgex, &desti)==0)
  197.     {
  198.       PrintMessage("Working ...");
  199.  
  200.       if (form==1) Do_It_plus();
  201.       else Do_It_normal();
  202.  
  203.       WritePGMFile(GetFilename(2,argc,argv),&desti);
  204.       FreePGMArray(&desti);
  205.     }
  206.  
  207.     FreePGMArray(&source);
  208.   }
  209.  
  210.   PrintClosing();
  211.   exit(0);
  212. }
  213.  
  214.